﻿
# python3 脚本程序：用于提取Bilibili缓存文件下载目录中的音视频文件，并转换为MP4格式
# set path=D:\gsoft\python\python38;%path%
# set path=D:\gsoft\ffmpeg-6.0\bin;%path%

import os
import json
import subprocess
import re

ffmpeg = 'ffmpeg' # ffmpeg 命令，要求安装ffmpeg, 并将ffmpeg设置到PATH路径变量中
src_dir = "F:\\Bilibili-tmp\\" # 待扫描Bilibili缓存文件下载目录，提取将手机/Android/data/tv.danmaku.bili/download下的所有目录复制到这个目录下
out_dir = 'F:\\Bilibili\\' # 转换后的mp4文件存放目录

# 剔除文件名中的特殊字符
def remove_illegal_characters(filename):
    return re.sub(r'[\s\r\n\\/\\*\\"\\<\\>\\|\\:\\：\\，\\,\\?\\？]', '', filename)

# 提取json文件中的owner_name和title字段值
def extract_owner_and_title(entry_json_path):
    with open(entry_json_path, 'r', encoding='utf-8') as json_file:
        data = json.load(json_file)
        owner_name = data.get('owner_name', '')
        title = data.get('title', '')
        type_tag = data.get('type_tag', '')
        return owner_name, title, type_tag

# 扫描所有目录且合并video.m4s和audio.m4s为mp4文件
def merge_va(src_dir, out_dir):
    if not os.path.isdir(src_dir):
        print('src_dir invalid')
        return 1
    if not os.path.isdir(out_dir):
        print('out_dir invalid')
        return 1
    src_dir = os.path.realpath(src_dir)
    out_dir = os.path.realpath(out_dir)
    root_level = len(src_dir.split(os.sep))
    # print('root_level:', root_level)
    for root, dirs, files in os.walk(src_dir):
        if len(root.split(os.sep)) - root_level == 2:
            entry_json_path = os.path.join(root, 'entry.json')
            if os.path.exists(entry_json_path):
                # print('entry_json_path:', entry_json_path)
                owner_name, title, type_tag = extract_owner_and_title(entry_json_path)
                out_owner_dir = os.path.join(out_dir, owner_name)
                out_path = os.path.join(out_owner_dir, remove_illegal_characters(title) + '.mp4')
                os.makedirs(out_owner_dir, exist_ok=True)
                if not os.path.exists(out_path):
                    video_m4s_path = os.path.join(root, type_tag, 'video.m4s')
                    audio_m4s_path = os.path.join(root, type_tag, 'audio.m4s')
                    cmd = ffmpeg + ' -i ' + video_m4s_path + ' -i ' + audio_m4s_path + ' -codec copy ' + out_path
                    print('execute:',cmd)
                    os.system(cmd)
            else:
                print('NOT FOUND entry_json_path:', entry_json_path)
    return 0

merge_va(src_dir, out_dir)
print('任务完成')
